#define _CRT_SECURE_NO_WARNINGS
#include <numeric>
#include <algorithm>
#include <iostream>
#include <sstream>
#include <fstream>
#include <string>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cctype>
#include <cmath>
using namespace std;
typedef vector<int> VI;
typedef vector<VI> VVI;
typedef vector<string> VS;
#define Rep(i,n) for(int i=0;i<(n);++i) 
#define For(i,a,b) for(int i=(a);i<=(b);++i) 
#define ForI(TP,i,coll) for(TP (i)=coll.begin();(i)!=coll.end();(i)++)
#define ForD(i,a,b) for(int i=(a);i>=(b);--i)
#define All(a) a.begin(), a.end()

#ifdef _MSC_VER
const int X=72;
#else
const int X=150;
#endif

const int W=180;

template<int N>
struct image
{
	bool empty;
	char d[N][N+1];
	void load()
	{
		Rep(i, N)
			scanf("%s", d[i]);
	}
	image()
	{
		empty=false;
		//Rep(i, N) d[i][N]=0; // string endding
	}
	// orig
	int diff1(image<N>* o)
	{
		int ret[8]={0};
		Rep(i, N)Rep(j, N)
		{
			// orig
			if(d[i][j]!=o->d[i][j])
				ret[0]++;
			// flips
			if(d[i][j]!=o->d[N-i][j])
				ret[1]++;
			if(d[i][j]!=o->d[i][N-j])
				ret[2]++;
			if(d[i][j]!=o->d[N-i][N-j])
				ret[3]++;
			// rotations
			if(d[i][j]!=o->d[j][i])
				ret[4]++;
			if(d[i][j]!=o->d[N-j][N-i])
				ret[5]++;
			if(d[i][j]!=o->d[N-j][i])
				ret[6]++;
			if(d[i][j]!=o->d[j][N-i])
				ret[7]++;
		}
		return *min_element(ret, ret+8);
	}
};

image<W> I[X];
const int NW=int(0.5*W);
image<NW> I2[X];

template<int N1, int N2>
void scale(image<N1>* src, image<N2>* des)
{
	int x1, y1, x2, y2;
	x1=y1=N1;
	x2=y2=0;

	Rep(x, N1)Rep(y,N1)
	{
		if(src->d[y][x])
		{
		x1=min(x1, x);
		y1=min(y1, y);
		x2=max(x2, x);
		y2=max(y2, y);
		}
	}
	int w=x2-x1, h=y2-y1;
	if(w<0 || h<0)
	{
		des->empty=true;
		memset(des->d, sizeof(des->d), '0');
		return;
	}
	else
		des->empty=false;

	double xrat=double(w)/double(N2);
	double yrat=double(h)/double(N2);

	Rep(x, N2) Rep(y, N2)
	{
		int sx=xrat*x+x1,
			sy=yrat*y+y1;

		//if(sx>=N1 || sy>=N1)
		//{
		//	cout<<"Error"<<endl;
		//}

		des->d[y][x]=
			src->d[sy][sx];
	}
};

static int diff[X][X];

struct img_diff
{
	int imgid;
	int dif;
	img_diff(int id=-1, int df=-1) : imgid(id), dif(df){}
};
bool operator<(const img_diff& d1, const img_diff& d2)
{
	return d1.dif<d2.dif;
}

int main()
{
	Rep(i, X)
	{
		I[i].load();
		scale(&I[i], &I2[i]);
	}

	Rep(i, X)
	{
		For(j, i+1, X-1)
		{
			diff[i][j]=diff[j][i]=I2[i].diff1(I2+j);
			//diff[i][j]=diff[j][i]=I[i].diff1(I+j);
		}
	}

	vector<img_diff> dfs(X);
	Rep(i, X)
	{
		Rep(j, X)
		{
			dfs[j].imgid=j;
			dfs[j].dif=diff[i][j];
		}

		sort(dfs.begin(), dfs.end());

		Rep(j, dfs.size())
		{
			if(j!=0)
				cout<< " ";
			cout<< dfs[j].imgid;
		}
		cout<<endl;

	}

	return 0;
}